struct Foo
  bar
  baz
end


struct HasPlain
  n::Int
  HasPlain() = new()
end

struct OrderedPair
  x::Real
  y::Real
  OrderedPair(x,y) = x > y ? error("out of order") : new(x,y)
end


try
println(OrderedPair(11,2))
catch e
   println(e)
finally
end

#Parametric Constructors
struct Point{T<:Real}
   x::T
   y::T
   Point{T}(x,y) where {T<:Real} = new(x,y) #Inner Constructor Methods
end
#Outer Constructor Methods
Point(x::T, y::T) where {T<:Real} = Point{T}(x,y);
Point(x::Int64, y::Float64) = Point(convert(Float64,x),y);
Point(x::Real, y::Real) = Point(promote(x,y)...);

println(Point(1,2.5))
println(Point(1.0,2))
println(Point(1,1//2))

#Case Study: Rational
struct OurRational{T<:Integer} <: Real
   num::T
   den::T
   function OurRational{T}(num::T, den::T) where T<:Integer
       if num == 0 && den == 0
            error("invalid rational: 0//0")
       end
       g = gcd(den, num)
       num = div(num, g)
       den = div(den, g)
       new(num, den)
   end
end

OurRational(n::T, d::T) where {T<:Integer} = OurRational{T}(n,d)

x = 4//6
y =2
println(x//y)
println(y//x)
println(OurRational(2,4))



#= Incomplete Initialization
mutable struct SelfReferential
   obj::SelfReferential
   SelfReferential() = (x = new(); x.obj = x)
end
x = SelfReferential();
println("SelfReferential:", x === x.obj)
=#
